





<!DOCTYPE html>
<html class="writer-html5" lang="zh-CN" >
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>Introduction to Module Serialization &mdash; tvm 0.8.dev1982 文档</title>
  

  
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../_static/gallery.css" type="text/css" />
  <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../_static/css/tlcpack_theme.css" type="text/css" />

  
  
    <link rel="shortcut icon" href="../_static/tvm-logo-square.png"/>
  

  
  
  
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
        <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
        <script src="../_static/jquery.js"></script>
        <script src="../_static/underscore.js"></script>
        <script src="../_static/doctools.js"></script>
        <script src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/js/theme.js"></script>

    
    <script type="text/javascript" src="../_static/js/tlcpack_theme.js"></script>
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="next" title="Device/Target Interactions" href="device_target_interactions.html" />
    <link rel="prev" title="Putting the VM in TVM: The Relay Virtual Machine" href="virtual_machine.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    
<header class="header">
    <div class="innercontainer">
      <div class="headerInner d-flex justify-content-between align-items-center">
          <div class="headerLogo">
               <a href="https://tvm.apache.org/"><img src=https://tvm.apache.org/assets/images/logo.svg alt="logo"></a>
          </div>

          <div id="headMenu" class="headerNav">
            <button type="button" id="closeHeadMenu" class="navCloseBtn"><img src="../_static/img/close-icon.svg" alt="Close"></button>
             <ul class="nav">
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/community>Community</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/download>Download</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/vta>VTA</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/blog>Blog</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvm.apache.org/docs>Docs</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvmconf.org>Conference</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://github.com/apache/tvm/>Github</a>
                </li>
                <li class="nav-item">
                   <a class="nav-link" href=https://tvmchinese.github.io/declaration_zh_CN.html>About-Translators</a>
                </li>
             </ul>
               <div class="responsivetlcdropdown">
                 <button type="button" class="btn-link">
                   ASF
                 </button>
                 <ul>
                     <li>
                       <a href=https://apache.org/>Apache Homepage</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/licenses/>License</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/sponsorship.html>Sponsorship</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/security/>Security</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/thanks.html>Thanks</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/events/current-event>Events</a>
                     </li>
                     <li>
                       <a href=https://www.zhihu.com/column/c_1429578595417563136>Zhihu</a>
                     </li>
                 </ul>
               </div>
          </div>
            <div class="responsiveMenuIcon">
              <button type="button" id="menuBtn" class="btn-menu"><img src="../_static/img/menu-icon.svg" alt="Menu Icon"></button>
            </div>

            <div class="tlcDropdown">
              <div class="dropdown">
                <button type="button" class="btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                  ASF
                </button>
                <div class="dropdown-menu dropdown-menu-right">
                  <ul>
                     <li>
                       <a href=https://apache.org/>Apache Homepage</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/licenses/>License</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/sponsorship.html>Sponsorship</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/security/>Security</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/foundation/thanks.html>Thanks</a>
                     </li>
                     <li>
                       <a href=https://www.apache.org/events/current-event>Events</a>
                     </li>
                     <li>
                       <a href=https://www.zhihu.com/column/c_1429578595417563136>Zhihu</a>
                     </li>
                  </ul>
                </div>
              </div>
          </div>
       </div>
    </div>
 </header>
 
    <nav data-toggle="wy-nav-shift" class="wy-nav-side fixed">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="../index.html">
          

          
            
            <img src="../_static/tvm-logo-small.png" class="logo" alt="Logo"/>
          
          </a>

          
            
            
                <div class="version">
                  0.8.dev1982
                </div>
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <p class="caption" role="heading"><span class="caption-text">如何开始</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../install/index.html">安装 TVM</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contribute/index.html">贡献者指南</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">用户引导</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">User Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../how_to/index.html">How To Guides</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">开发者引导</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../dev/tutorial/index.html">Developer Tutorial</a></li>
<li class="toctree-l1"><a class="reference internal" href="../dev/how_to/how_to.html">开发者指南</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">架构指南</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Design and Architecture</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="index.html#example-compilation-flow">编译流程示例</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#logical-architecture-components">逻辑架构组件</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-support">tvm/support</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html#tvm-runtime">tvm/runtime</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="runtime.html">TVM runtime系统</a></li>
<li class="toctree-l3"><a class="reference internal" href="runtime.html#runtime-specific-information">Runtime-Specific Information</a></li>
<li class="toctree-l3"><a class="reference internal" href="debugger.html">Debugger</a></li>
<li class="toctree-l3"><a class="reference internal" href="virtual_machine.html">Putting the VM in TVM: The Relay Virtual Machine</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Introduction to Module Serialization</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#module-export-example">Module Export Example</a></li>
<li class="toctree-l4"><a class="reference internal" href="#serialization">Serialization</a></li>
<li class="toctree-l4"><a class="reference internal" href="#under-the-hood-of-serialization-and-format-standard">Under the Hood of Serialization and Format Standard</a></li>
<li class="toctree-l4"><a class="reference internal" href="#deserialization">Deserialization</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="device_target_interactions.html">Device/Target Interactions</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-node">tvm/node</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-ir">tvm/ir</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-target">tvm/target</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-tir">tvm/tir</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-arith">tvm/arith</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-te">tvm/te</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-topi">tvm/topi</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-relay">tvm/relay</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#tvm-autotvm">tvm/autotvm</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#frontends">Frontends</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#security">安全</a></li>
<li class="toctree-l2"><a class="reference internal" href="index.html#microtvm">microTVM</a></li>
</ul>
</li>
</ul>
<p class="caption" role="heading"><span class="caption-text">主题引导</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../topic/microtvm/index.html">microTVM：裸机使用TVM</a></li>
<li class="toctree-l1"><a class="reference internal" href="../topic/vta/index.html">VTA: Versatile Tensor Accelerator</a></li>
</ul>
<p class="caption" role="heading"><span class="caption-text">参考指南</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../reference/langref/index.html">语言参考</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/api/python/index.html">Python API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/api/links.html">Other APIs</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/publications.html">Publications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../genindex.html">索引</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
      
      <nav class="wy-nav-top" aria-label="top navigation" data-toggle="wy-nav-top">
        
            <div class="togglemenu">

            </div>
            <div class="nav-content">
              <!-- tvm -->
              Table of content
            </div>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        

          




















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../index.html">Docs</a> <span class="br-arrow">></span></li>
        
          <li><a href="index.html">Design and Architecture</a> <span class="br-arrow">></span></li>
        
      <li>Introduction to Module Serialization</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
            
            <a href="../_sources/arch/introduction_to_module_serialization.rst.txt" rel="nofollow"> <img src="../_static//img/source.svg" alt="viewsource"/></a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <div class="section" id="introduction-to-module-serialization">
<h1>Introduction to Module Serialization<a class="headerlink" href="#introduction-to-module-serialization" title="永久链接至标题">¶</a></h1>
<p>When to deploy TVM runtime module, no matter whether it is CPU or GPU, TVM only needs one single dynamic
shared library. The key is our unified module serialization mechanism. This document will introduce TVM module
serialization format standard and implementation details.</p>
<div class="section" id="module-export-example">
<h2>Module Export Example<a class="headerlink" href="#module-export-example" title="永久链接至标题">¶</a></h2>
<p>Let us build one ResNet-18 workload for GPU as an example first.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">tvm</span> <span class="kn">import</span> <span class="n">relay</span>
<span class="kn">from</span> <span class="nn">tvm.relay</span> <span class="kn">import</span> <span class="n">testing</span>
<span class="kn">from</span> <span class="nn">tvm.contrib</span> <span class="kn">import</span> <span class="n">utils</span>
<span class="kn">import</span> <span class="nn">tvm</span>

<span class="c1"># Resnet18 workload</span>
<span class="n">resnet18_mod</span><span class="p">,</span> <span class="n">resnet18_params</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">testing</span><span class="o">.</span><span class="n">resnet</span><span class="o">.</span><span class="n">get_workload</span><span class="p">(</span><span class="n">num_layers</span><span class="o">=</span><span class="mi">18</span><span class="p">)</span>

<span class="c1"># build</span>
<span class="k">with</span> <span class="n">relay</span><span class="o">.</span><span class="n">build_config</span><span class="p">(</span><span class="n">opt_level</span><span class="o">=</span><span class="mi">3</span><span class="p">):</span>
    <span class="n">_</span><span class="p">,</span> <span class="n">resnet18_lib</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">relay</span><span class="o">.</span><span class="n">build_module</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="n">resnet18_mod</span><span class="p">,</span> <span class="s2">&quot;cuda&quot;</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">resnet18_params</span><span class="p">)</span>

<span class="c1"># create one tempory directory</span>
<span class="n">temp</span> <span class="o">=</span> <span class="n">utils</span><span class="o">.</span><span class="n">tempdir</span><span class="p">()</span>

<span class="c1"># path lib</span>
<span class="n">file_name</span> <span class="o">=</span> <span class="s2">&quot;deploy.so&quot;</span>
<span class="n">path_lib</span> <span class="o">=</span> <span class="n">temp</span><span class="o">.</span><span class="n">relpath</span><span class="p">(</span><span class="n">file_name</span><span class="p">)</span>

<span class="c1"># export library</span>
<span class="n">resnet18_lib</span><span class="o">.</span><span class="n">export_library</span><span class="p">(</span><span class="n">path_lib</span><span class="p">)</span>

<span class="c1"># load it back</span>
<span class="n">loaded_lib</span> <span class="o">=</span> <span class="n">tvm</span><span class="o">.</span><span class="n">runtime</span><span class="o">.</span><span class="n">load_module</span><span class="p">(</span><span class="n">path_lib</span><span class="p">)</span>
<span class="k">assert</span> <span class="n">loaded_lib</span><span class="o">.</span><span class="n">type_key</span> <span class="o">==</span> <span class="s2">&quot;library&quot;</span>
<span class="k">assert</span> <span class="n">loaded_lib</span><span class="o">.</span><span class="n">imported_modules</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">type_key</span> <span class="o">==</span> <span class="s2">&quot;cuda&quot;</span>
</pre></div>
</div>
</div>
<div class="section" id="serialization">
<h2>Serialization<a class="headerlink" href="#serialization" title="永久链接至标题">¶</a></h2>
<p>The entrance API is <code class="docutils literal notranslate"><span class="pre">export_library</span></code> of <code class="docutils literal notranslate"><span class="pre">tvm.module.Module</span></code>.
Inside this function, we will do the following steps:</p>
<ol class="arabic simple">
<li><p>Collect all DSO modules (LLVM modules and C modules)</p></li>
<li><p>Once we have DSO modules, we will call <code class="docutils literal notranslate"><span class="pre">save</span></code> function to save them into files.</p></li>
<li><p>Next, we will check whether we have imported modules, such as CUDA,
OpenCL or anything else. We don’t restrict the module type here.
Once we have imported modules, we will create one file named <code class="docutils literal notranslate"><span class="pre">devc.o</span></code> / <code class="docutils literal notranslate"><span class="pre">dev.cc</span></code>
(so that we could embed the binary blob data of import modules into one dynamic shared library),
then call function <code class="docutils literal notranslate"><span class="pre">_PackImportsToLLVM</span></code> or <code class="docutils literal notranslate"><span class="pre">_PackImportsToC</span></code> to do module serialization.</p></li>
<li><p>Finally, we call <code class="docutils literal notranslate"><span class="pre">fcompile</span></code> which invokes <code class="docutils literal notranslate"><span class="pre">_cc.create_shared</span></code> to get
dynamic shared library.</p></li>
</ol>
<div class="admonition note">
<p class="admonition-title">注解</p>
<ol class="arabic simple">
<li><p>For C source modules, we will compile them and link them together with the DSO module.</p></li>
<li><p>Use <code class="docutils literal notranslate"><span class="pre">_PackImportsToLLVM</span></code> or <code class="docutils literal notranslate"><span class="pre">_PackImportsToC</span></code> depends on whether we enable LLVM in TVM.
They achieve the same goal in fact.</p></li>
</ol>
</div>
</div>
<div class="section" id="under-the-hood-of-serialization-and-format-standard">
<h2>Under the Hood of Serialization and Format Standard<a class="headerlink" href="#under-the-hood-of-serialization-and-format-standard" title="永久链接至标题">¶</a></h2>
<p>As said before, we will do the serialization work in the <code class="docutils literal notranslate"><span class="pre">_PackImportsToLLVM</span></code> or <code class="docutils literal notranslate"><span class="pre">_PackImportsToC</span></code>.
They both call <code class="docutils literal notranslate"><span class="pre">SerializeModule</span></code> to serialize the runtime module. In <code class="docutils literal notranslate"><span class="pre">SerializeModule</span></code>
function, we firstly construct one helper class <code class="docutils literal notranslate"><span class="pre">ModuleSerializer</span></code>. It will take <code class="docutils literal notranslate"><span class="pre">module</span></code> to do some
initialization work, like marking module index. Then we could use its <code class="docutils literal notranslate"><span class="pre">SerializeModule</span></code> to serialize module.</p>
<p>For better understanding, let us dig the implementation of this class a little deeper.</p>
<p>The following code is used to construct <code class="docutils literal notranslate"><span class="pre">ModuleSerializer</span></code>:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="k">explicit</span> <span class="nf">ModuleSerializer</span><span class="p">(</span><span class="n">runtime</span><span class="o">::</span><span class="n">Module</span> <span class="n">mod</span><span class="p">)</span> <span class="o">:</span> <span class="n">mod_</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">Init</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="kt">void</span> <span class="n">Init</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">CreateModuleIndex</span><span class="p">();</span>
  <span class="n">CreateImportTree</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In <code class="docutils literal notranslate"><span class="pre">CreateModuleIndex()</span></code>, We will inspect module import relationship
using DFS and create index for them. Note the root module is fixed at
location 0. In our example, we have module relationship like this:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="nl">llvm_mod</span><span class="p">:</span><span class="n">imported_modules</span>
  <span class="o">-</span> <span class="n">cuda_mod</span>
</pre></div>
</div>
<p>So LLVM module will have index 0, CUDA module will have index 1.</p>
<p>After constructing module index, we will try to construct import tree (<code class="docutils literal notranslate"><span class="pre">CreateImportTree()</span></code>),
which will be used to restore module import relationship when we load
the exported library back. In our design, we use CSR format to store
import tree, each row is parent index, the child indices correspond to its children
index. In code, we use <code class="docutils literal notranslate"><span class="pre">import_tree_row_ptr_</span></code> and
<code class="docutils literal notranslate"><span class="pre">import_tree_child_indices_</span></code> to represent them.</p>
<p>After initialization, we could serialize module using <code class="docutils literal notranslate"><span class="pre">SerializeModule</span></code> function.
In its function logic, we will assume the serialization format like this:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">binary_blob_size</span>
<span class="n">binary_blob_type_key</span>
<span class="n">binary_blob_logic</span>
<span class="n">binary_blob_type_key</span>
<span class="n">binary_blob_logic</span>
<span class="p">...</span>
<span class="n">_import_tree</span>
<span class="n">_import_tree_logic</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">binary_blob_size</span></code> is the number of blobs we will have in this
serialization step. There will be three blobs in our example which
are created for LLVM module, CUDA module, and <code class="docutils literal notranslate"><span class="pre">_import_tree</span></code>, respectively.</p>
<p><code class="docutils literal notranslate"><span class="pre">binary_blob_type_key</span></code> is the blob type key of module. For LLVM / C module, whose
blob type key is <code class="docutils literal notranslate"><span class="pre">_lib</span></code>. For CUDA module, it is <code class="docutils literal notranslate"><span class="pre">cuda</span></code>, which could be got by <code class="docutils literal notranslate"><span class="pre">module-&gt;type_key()</span></code>.</p>
<p><code class="docutils literal notranslate"><span class="pre">binary_blob_logic</span></code> is the logic handling of blob. For most of blob (like CUDA, OpenCL), we will call
<code class="docutils literal notranslate"><span class="pre">SaveToBinary</span></code> function to serialize blob into binary. However, like LLVM / C module, we will only write
<code class="docutils literal notranslate"><span class="pre">_lib</span></code> to indicate this is a DSO module.</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>Whether or not it is required to implement the SaveToBinary virtual function depends on
how the module is used. For example, If the module has information we need when we load
the dynamic shared library back, we should do. Like CUDA module, we need its binary data
passing to GPU driver when we load the dynamic shared library, so we should implement
<code class="docutils literal notranslate"><span class="pre">SaveToBinary</span></code> to serialize its binary data. But for host module (like DSO), we don’t
need other information when we load the dynamic shared library, so we don’t need to implement
<code class="docutils literal notranslate"><span class="pre">SaveToBinary</span></code>. However, if in the future, we want to record some meta information of DSO module,
we could implement <code class="docutils literal notranslate"><span class="pre">SaveToBinary</span></code> for DSO module too.</p>
</div>
<p>Finally, we will write one key <code class="docutils literal notranslate"><span class="pre">_import_tree</span></code> unless our module only
has one DSO module and it is in the root. It is used to reconstruct the
module import relationship when we load the exported library back as said
before. The <code class="docutils literal notranslate"><span class="pre">import_tree_logic</span></code> is just to write <code class="docutils literal notranslate"><span class="pre">import_tree_row_ptr_</span></code>
and <code class="docutils literal notranslate"><span class="pre">import_tree_child_indices_</span></code> into stream.</p>
<p>After this step, we will pack it into a symbol
<code class="docutils literal notranslate"><span class="pre">runtime::symbol::tvm_dev_mblob</span></code> that can be recovered in the dynamic
libary.</p>
<p>Now, we complete the serialization part. As you have seen, we could
support arbitrary modules to import ideally.</p>
</div>
<div class="section" id="deserialization">
<h2>Deserialization<a class="headerlink" href="#deserialization" title="永久链接至标题">¶</a></h2>
<p>The entrance API is <code class="docutils literal notranslate"><span class="pre">tvm.runtime.load</span></code>. This function
is to call <code class="docutils literal notranslate"><span class="pre">_LoadFromFile</span></code> in fact. If we dig it a little deeper, this is
<code class="docutils literal notranslate"><span class="pre">Module::LoadFromFile</span></code>. In our example, the file is <code class="docutils literal notranslate"><span class="pre">deploy.so</span></code>,
according to the function logic, we will call <code class="docutils literal notranslate"><span class="pre">module.loadfile_so</span></code> in
<code class="docutils literal notranslate"><span class="pre">dso_library.cc</span></code>. The key is here:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="c1">// Load the imported modules</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">dev_mblob</span> <span class="o">=</span> <span class="k">reinterpret_cast</span><span class="o">&lt;</span><span class="k">const</span> <span class="kt">char</span><span class="o">*&gt;</span><span class="p">(</span><span class="n">lib</span><span class="o">-&gt;</span><span class="n">GetSymbol</span><span class="p">(</span><span class="n">runtime</span><span class="o">::</span><span class="n">symbol</span><span class="o">::</span><span class="n">tvm_dev_mblob</span><span class="p">));</span>
<span class="n">Module</span> <span class="n">root_mod</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">dev_mblob</span> <span class="o">!=</span> <span class="k">nullptr</span><span class="p">)</span> <span class="p">{</span>
<span class="n">root_mod</span> <span class="o">=</span> <span class="n">ProcessModuleBlob</span><span class="p">(</span><span class="n">dev_mblob</span><span class="p">,</span> <span class="n">lib</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="c1">// Only have one single DSO Module</span>
<span class="n">root_mod</span> <span class="o">=</span> <span class="n">Module</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>As said before, we will pack the blob into the symbol
<code class="docutils literal notranslate"><span class="pre">runtime::symbol::tvm_dev_mblob</span></code>. During deserialization part, we will
inspect it. If we have <code class="docutils literal notranslate"><span class="pre">runtime::symbol::tvm_dev_mblob</span></code>, we will call <code class="docutils literal notranslate"><span class="pre">ProcessModuleBlob</span></code>,
whose logic like this:</p>
<div class="highlight-c++ notranslate"><div class="highlight"><pre><span></span><span class="n">READ</span><span class="p">(</span><span class="n">blob_size</span><span class="p">)</span>
<span class="n">READ</span><span class="p">(</span><span class="n">blob_type_key</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">blob_size</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">blob_type_key</span> <span class="o">==</span> <span class="s">&quot;_lib&quot;</span><span class="p">)</span> <span class="p">{</span>
      <span class="c1">// construct dso module using lib</span>
    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">blob_type_key</span> <span class="o">==</span> <span class="s">&quot;_import_tree&quot;</span><span class="p">)</span> <span class="p">{</span>
      <span class="c1">// READ(_import_tree_row_ptr)</span>
      <span class="c1">// READ(_import_tree_child_indices)</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="c1">// call module.loadbinary_blob_type_key, such as module.loadbinary_cuda</span>
      <span class="c1">// to restore.</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Using _import_tree_row_ptr and _import_tree_child_indices to</span>
<span class="c1">// restore module import relationship. The first module is the</span>
<span class="c1">// root module according to our invariance as said before.</span>
<span class="k">return</span> <span class="n">root_module</span><span class="p">;</span>
</pre></div>
</div>
<p>After this, we will set the <code class="docutils literal notranslate"><span class="pre">ctx_address</span></code> to be the <code class="docutils literal notranslate"><span class="pre">root_module</span></code> so
that allow lookup of symbol from root (so all symbols are visible).</p>
<p>Finally, we complete the deserialization part.</p>
</div>
</div>


           </div>
           
          </div>
          

<footer>

    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="device_target_interactions.html" class="btn btn-neutral float-right" title="Device/Target Interactions" accesskey="n" rel="next">下一个 <span class="fa fa-arrow-circle-right"></span></a>
      
      
        <a href="virtual_machine.html" class="btn btn-neutral float-left" title="Putting the VM in TVM: The Relay Virtual Machine" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> 上一个</a>
      
    </div>

<div id="button" class="backtop"><img src="../_static//img/right.svg" alt="backtop"/> </div>
<section class="footerSec">
    <div class="footerHeader">
      <ul class="d-flex align-md-items-center justify-content-between flex-column flex-md-row">
        <li class="copywrite d-flex align-items-center">
          <h5 id="copy-right-info">© 2020 Apache Software Foundation | All right reserved</h5>
        </li>
      </ul>

    </div>

    <ul>
      <li class="footernote">Copyright © 2020 The Apache Software Foundation. Apache TVM, Apache, the Apache feather, and the Apache TVM project logo are either trademarks or registered trademarks of the Apache Software Foundation.</li>
    </ul>

</section>
</footer>
        </div>
      </div>

    </section>

  </div>
  

    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

  </body>
  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
    <!-- Theme Analytics -->
    <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-75982049-2', 'auto');
    ga('send', 'pageview');
    </script>

    
   

</body>
</html>